package site.lianwu.mybatis.plus.query;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import site.lianwu.mybatis.plus.query.processor.GeneralQueryWrapperProcessor;
import site.lianwu.mybatis.plus.query.processor.QueryWrapperProcessor;

import java.util.Objects;

/**
 * 条件包装工具，{@link QueryWrapperProcessor}的外观类
 * <ul>
 *     <li>
 *         默认使用{@link GeneralQueryWrapperProcessor}进行解析，可通过{@link #initQueryWrapperProcessor(QueryWrapperProcessor)}初始化自定义{@code QueryWrapperProcessor}
 *     </li>
 *     <li>
 *         {@link QueryOption}用于补充构建分组的查询条件
 *     </li>
 * </ul>
 *
 * @author LianWu
 */
public class QueryWrappers {

    /**
     * 条件包装处理器，负责解析条件对象，生成条件包装{@code QueryWrapper}
     */
    private static volatile QueryWrapperProcessor queryWrapperProcessor;

    private QueryWrappers() {}

    /**
     * 解析条件对象，仅解析类中声明的字段
     *
     * @param obj 条件对象
     * @return 条件包装
     * @param <T> 查询结果类型
     */
    public static <T> QueryWrapper<T> parse(Object obj) {
        return getOrInitDefaultQueryWrapperProcessor().parse(obj, false, null);
    }

    /**
     * 解析条件对象，不仅包含类中声明的字段，还支持解析继承的字段
     *
     * @param obj 条件对象
     * @param includeInheritedFields 是否包含继承字段
     * @return 条件包装
     * @param <T> 查询结果类型
     */
    public static <T> QueryWrapper<T> parse(Object obj, boolean includeInheritedFields) {
        return getOrInitDefaultQueryWrapperProcessor().parse(obj, includeInheritedFields, null);
    }

    /**
     * 解析条件对象，仅解析类中声明的字段，支持查询选项配置
     *
     * @param obj 条件对象
     * @param option 查询选项，可补充分组的查询条件构建
     * @return 条件包装
     * @param <T> 查询结果类型
     */
    public static <T> QueryWrapper<T> parse(Object obj, QueryOption<T> option) {
        return getOrInitDefaultQueryWrapperProcessor().parse(obj, false, option);
    }

    /**
     * 解析条件对象，不仅包含类中声明的字段，还支持解析继承的字段、查询选项配置
     *
     * @param obj 条件对象
     * @param includeInheritedFields 是否包含继承字段
     * @param option 查询选项，可补充分组的查询条件构建
     * @return 条件包装
     * @param <T> 查询结果类型
     */
    public static <T> QueryWrapper<T> parse(Object obj, boolean includeInheritedFields, QueryOption<T> option) {
        return getOrInitDefaultQueryWrapperProcessor().parse(obj, includeInheritedFields, option);
    }

    /**
     * 初始化条件包装处理器，<strong>最多允许一次初始化</strong>
     * <p><strong>请确保在调用任何解析方法前初始化自定义{@code QueryWrapperProcessor}</strong></p>
     *
     * @param queryWrapperProcessor 条件包装处理器
     * @throws IllegalStateException 若已初始化条件包装处理器
     */
    public static void initQueryWrapperProcessor(QueryWrapperProcessor queryWrapperProcessor) {
        Objects.requireNonNull(queryWrapperProcessor);
        synchronized (QueryWrappers.class) {
            if (QueryWrappers.queryWrapperProcessor != null) {
                throw new IllegalStateException("QueryWrapperProcessor已经初始化了");
            }
            QueryWrappers.queryWrapperProcessor = queryWrapperProcessor;
        }
    }

    /**
     * 获取条件包装处理器实例
     * <p>若未指定{@code QueryWrapperProcessor}，默认使用双检锁模式懒汉式初始化{@link GeneralQueryWrapperProcessor}进行解析</p>
     *
     * <p>可调用{@link QueryWrappers#initQueryWrapperProcessor(QueryWrapperProcessor)}初始化自定义处理器</p>
     *
     * @return 条件包装处理器实例
     */
    private static QueryWrapperProcessor getOrInitDefaultQueryWrapperProcessor() {
        if (queryWrapperProcessor == null) {
            synchronized (QueryWrappers.class) {
                if (queryWrapperProcessor == null) {
                    queryWrapperProcessor = new GeneralQueryWrapperProcessor();
                }
            }
        }
        return queryWrapperProcessor;
    }

}
